package br.com.sgi.bean;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.faces.model.SelectItem;
import javax.swing.ListModel;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Controller;

import br.com.sgi.autentication.UsuarioLogado;
import br.com.sgi.model.Authorities;
import br.com.sgi.model.Authority;
import br.com.sgi.model.Igreja;
import br.com.sgi.model.Users;
import br.com.sgi.model.UsersIgreja;
import br.com.sgi.service.AuthoritiesService;
import br.com.sgi.service.AuthorityService;
import br.com.sgi.service.IgrejaService;
import br.com.sgi.service.SistemaService;
import br.com.sgi.service.UsersIgrejaService;
import br.com.sgi.service.UsersService;
import br.com.sgi.util.Constante;
import br.com.sgi.util.Criptografia;
import br.com.sgi.util.Mensagem;
import br.com.sgi.util.email.EmailService;
import br.com.sgi.util.email.EnviaEmail;
/**
 * 
 * @author lucas.costa
 *
 */
@Controller("usersCadastro")
@Scope("request")
public class UsersCadastroBean {
	
	private Users users;
	
	@Autowired
	private UsersService usersService;
	
	@Autowired
	private IgrejaService igrejaService;
	
	@Autowired
	private AuthoritiesService authoritiesService;
	
	@Autowired
	private AuthorityService authorityService;
	
	@Autowired
	private SistemaService sistemaService;
	
	@Autowired
	private UsersIgrejaService usersIgrejaService;
	
	private List<UsersIgreja> listaUsersIgrejaCadastradas;
	
	private List<Authority> listaAuthority;
	
	private List<Igreja> listaIgrejas;
	
	private List <Users> listaUsers;
	
	private List<SelectItem> listaSelctItensIgrejas;
	
	protected List<Long> listaIgrejasSelecionadas;
	
	private List<String> listaSelctItensIgrejasSelecionada;
	
	private boolean edicao =  false;
	
	private String SENHA_PADRAO = "123456";
	
	private String username;
	
	
	private Authority authority;

	private boolean usersJaExiste(){
		boolean jaExiste = false;
		if(username.equals(users.getUsername()))
			return jaExiste;
		if(users != null)
			if(usersService.buscarUsersPorUsername(users.getUsername()) != null && usersService.buscarUsersPorUsername(users.getUsername()).size() > 0)
				jaExiste = true;
		
		return jaExiste;
	}
	
	public void limpar(){
		users = new Users();
		listaIgrejasSelecionadas = new ArrayList<Long>();
		authority = new Authority();
		edicao = false;
	}
	
	public void salvar(){
		
		if(!usersJaExiste() && !edicao){
			
			users.setPassword(Criptografia.md5(SENHA_PADRAO));
			users.setEnabled(true);
			users.setPrimeiroAcesso(true);
			users.setSistema(sistemaService.findById(UsuarioLogado.getCoSistema()));
			
			Authorities authorities = new Authorities();
			authorities.setUsername(users);
			authorities.setAuthority(authority.getAuthority());
			authorities.setSistema(sistemaService.findById(UsuarioLogado.getCoSistema()));
			
			List<Authorities> listAuthorities = new ArrayList<Authorities>();
			listAuthorities.add(authorities);
			users.setAuthorities(listAuthorities);
			usersService.salvar(users);
			
			if(authority != null && authority.getAuthority().equals(Constante.ROLE_ADMIN_REGIONAL) && listaIgrejasSelecionadas.size() > 0){
				salvarUsersIgreja(listaIgrejasSelecionadas);
			}
			
			Mensagem.infoMsg("sucesso.MGS_02");
			
		}
		else
			if(!usersJaExiste() && edicao){
				edicao = false;
				
				
				Authorities autho = authoritiesService.buscarAuthoritiesPorUsername(username);
				
				List<Authorities> listAuthorities = new ArrayList<Authorities>();
				autho.setAuthority(authority.getAuthority());
				listAuthorities.add(autho);
				users.setAuthorities(listAuthorities);
				
				if(users.getPrimeiroAcesso()){
					users.setPassword(Criptografia.md5(SENHA_PADRAO));
					EnviaEmail enviaEmail = new EnviaEmail();

//					enviaEmail.setDe(users.getEmail());
//					enviaEmail.setPara(membro.getEmail());
//					enviaEmail.setAssunto(titulo);
//					enviaEmail.setMensagem(textoEmail);
//					enviaEmail.enviar();
				}
				
				usersService.atualizar(users);
				removerUsersIgreja(users.getUsername());
				if(authority != null && authority.getAuthority().equals(Constante.ROLE_ADMIN_REGIONAL) && listaIgrejasSelecionadas.size() > 0){
					salvarUsersIgreja(listaIgrejasSelecionadas);
				}
				Mensagem.infoMsg("sucesso.MGS_03");
				
				limpar();
			}else
				Mensagem.errorMsg("erro.MSG_05");
		
	}
	
	
	private String senhaPrimeiroAcesso(){
		String senha = "";
		
		for(int  i = 0; i < 5; i++){
			senha = senha + Math.random();
		}
		
		return senha;
	}
	
	
	private void salvarUsersIgreja(List<Long> listaIgrejasSelecionadas){
		UsersIgreja usersIgreja = new UsersIgreja();
		for(Long id: listaIgrejasSelecionadas){
			usersIgreja = new UsersIgreja();
			usersIgreja.setIgreja(igrejaService.buscarIgrejaPorId(id));
			usersIgreja.setUsers(users);
			usersIgrejaService.salvar(usersIgreja);
		}
	}
	
	
	
	
	private void removerUsersIgreja(String username){
		List<UsersIgreja> listUsersIgrejas = usersIgrejaService.buscarUsersIgrejaPorCoUsers(username);
		if(listUsersIgrejas != null && listUsersIgrejas.size() > 0){
			for(UsersIgreja usersIgreja : listUsersIgrejas){
				usersIgrejaService.excluir(usersIgreja.getCoSeqUsersIgreja());
			}
		}
	}

	/**
	 * carregar coUsersIgreja cadastrados
	 * @param username
	 * @return
	 */
	private List<Long> carregarCoUsersIgreja(String username){
		List<UsersIgreja> listUi = 		usersIgrejaService.buscarUsersIgrejaPorCoUsers(username);
		List<Long> listCoUi = new ArrayList<Long>();
		for(UsersIgreja ui:listUi){
			listCoUi.add(ui.getIgreja().getCoSeqIgreja());
		}
		
		return listCoUi;
	}
	
	/**
	 * realiza a edicao dos dados do users
	 */
	public void editar(){
		edicao = true;
		username = users.getUsername();
		if(users.getIgreja() != null){
		List<Igreja> igrejas = igrejaService.buscarIgrejasPorCoSistema(UsuarioLogado.getCoSistema(), users.getIgreja().getCoSeqIgreja());
			listaSelctItensIgrejas = new ArrayList<SelectItem>();
			for(Igreja igreja: igrejas){
				listaSelctItensIgrejas.add(new SelectItem(igreja.getCoSeqIgreja(), igreja.getNome()));
			}
		}
		Collection<GrantedAuthority> autho = users.getAuthorities();
		Iterator<GrantedAuthority> itAutho = autho.iterator();
		listaIgrejasSelecionadas = carregarCoUsersIgreja(users.getUsername());
		while(itAutho.hasNext()){
			authority = obterAuthority(itAutho.next().getAuthority());
		}
	}
	
	private Authority obterAuthority(String role) {
		for(Authority aut: listaAuthority){
			if(aut.getAuthority().equals(role)){
				return this.authority = aut;
			}
		}
		return null;
	}

	/**
	 * realiza a exclucao de uma funcao
	 */
	public void excluir(){
		if(username != null){
			usersService.excluir(username);
			listaUsers = usersService.buscarUsersPorCoSistema();
			users = new Users();
			Mensagem.infoMsg("sucesso.MSG_01");
		}
		
	}
	
	
	/**
	 * select itens do pick liste
	 * @return
	 */
	public List<SelectItem> getListaSelctItensIgrejas() {
		List<Igreja> igrejas = igrejaService.buscarIgrejasPorCoSistema(UsuarioLogado.getCoSistema());
		if(listaSelctItensIgrejas == null){
			listaSelctItensIgrejas = new ArrayList<SelectItem>();
			for(Igreja igreja: igrejas){
				listaSelctItensIgrejas.add(new SelectItem(igreja.getCoSeqIgreja(), igreja.getNome()));
			}
		}
		
		return listaSelctItensIgrejas;
	}

	public void setListaSelctItensIgrejas(List<SelectItem> listaSelctItensIgrejas) {
		this.listaSelctItensIgrejas = listaSelctItensIgrejas;
	}
	
	/**
	 * get ids das igrejas cadastradas ao usuario
	 * @return
	 */
	private List<Long> getListaIdsUsersIgrejaCadastradas(){
		List<Long> listaIds = new ArrayList<Long>();
		
		listaUsersIgrejaCadastradas = usersIgrejaService.buscarUsersIgrejaPorCoUsers(UsuarioLogado.getUsernameUsuarioLogado());
		if(listaUsersIgrejaCadastradas != null){
			for(UsersIgreja usersIgreja: listaUsersIgrejaCadastradas){
				listaIds.add(usersIgreja.getIgreja().getCoSeqIgreja());
			}
		}
		
		return listaIds;
	}
	
	public Users getUsers() {
		if(users == null)
			users = new Users();
		return users;
	}

	public void setUsers(Users users) {
//		this.users = users;
//		Collection<GrantedAuthority> grantAuthorities = users.getAuthorities();
//		List<Authorities> authorities = new ArrayList<Authorities>();
// 		for(GrantedAuthority ga: grantAuthorities){
//			authority.setAuthority(ga.getAuthority());
//		}
		this.users = users;
	}

	
	public List<Authority> getListaAuthority() {
		if(listaAuthority == null)
			listaAuthority = authorityService.buscarTodasAuthority();
		return listaAuthority;
	}

	public void setListaAuthority(List<Authority> listaAuthority) {
		this.listaAuthority = listaAuthority;
	}

	public List<Igreja> getListaIgrejas() {
		if(listaIgrejas == null)
			listaIgrejas = igrejaService.buscarIgrejasPorCoSistema(UsuarioLogado.getCoSistema());
		return listaIgrejas;
	}

	public void setListaIgrejas(List<Igreja> listaIgrejas) {
		this.listaIgrejas = listaIgrejas;
	}

	/**
	 * lista com ids das igrejas cadastradas a um usuÃ¡rio
	 * @return
	 */
	public List<Long> getListaIgrejasSelecionadas() {
		if(listaIgrejasSelecionadas == null)
			listaIgrejasSelecionadas = getListaIdsUsersIgrejaCadastradas() != null? getListaIdsUsersIgrejaCadastradas(): new ArrayList<Long>();
		return listaIgrejasSelecionadas;
	}

	public void setListaIgrejasSelecionadas(List<Long> listaIgrejasSelecionadas) {
		this.listaIgrejasSelecionadas = listaIgrejasSelecionadas;
	}

	public List<Users> getListaUsers() {
		if(listaUsers == null)
			listaUsers = usersService.buscarUsersPorCoSistema();
		return listaUsers;
	}

	public void setListaUsers(List<Users> listaUsers) {
		this.listaUsers = listaUsers;
	}

	public Authority getAuthority() {
		if(authority == null)
			authority = new Authority();
		return authority;
	}

	public void setAuthority(Authority authority) {
		this.authority = authority;
	}

	public List<String> getListaSelctItensIgrejasSelecionada() {
		return listaSelctItensIgrejasSelecionada;
	}

	public void setListaSelctItensIgrejasSelecionada(
			List<String> listaSelctItensIgrejasSelecionada) {
		this.listaSelctItensIgrejasSelecionada = listaSelctItensIgrejasSelecionada;
	}

	public boolean isEdicao() {
		return edicao;
	}

	public void setEdicao(boolean edicao) {
		this.edicao = edicao;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}


	

}
